<?php

namespace core;

use core\Config;

class Log {
    const EMERGENCY = 'emergency';
    const ALERT = 'alert';
    const CRITICAL = 'critical';
    const ERROR = 'error';
    const WARNING = 'warning';
    const NOTICE = 'notice';
    const INFO = 'info';
    const DEBUG = 'debug';

    protected static $levels = [
        'emergency' => 0,
        'alert' => 1,
        'critical' => 2,
        'error' => 3,
        'warning' => 4,
        'notice' => 5,
        'info' => 6,
        'debug' => 7
    ];

    public static function emergency($message, array $context = []) {
        self::log(self::EMERGENCY, $message, $context);
    }

    public static function alert($message, array $context = []) {
        self::log(self::ALERT, $message, $context);
    }

    public static function critical($message, array $context = []) {
        self::log(self::CRITICAL, $message, $context);
    }

    public static function error($message, array $context = []) {
        self::log(self::ERROR, $message, $context);
    }

    public static function warning($message, array $context = []) {
        self::log(self::WARNING, $message, $context);
    }

    public static function notice($message, array $context = []) {
        self::log(self::NOTICE, $message, $context);
    }

    public static function info($message, array $context = []) {
        self::log(self::INFO, $message, $context);
    }

    public static function debug($message, array $context = []) {
        self::log(self::DEBUG, $message, $context);
    }

    public static function log($level, $message, array $context = []) {
        if (!isset(self::$levels[$level])) {
            throw new \InvalidArgumentException('Invalid log level: '.$level);
        }

        $logPath = Config::get('log.path', APP_PATH.'logs/');
        if (!is_dir($logPath)) {
            mkdir($logPath, 0755, true);
        }

        $logFile = $logPath.date('Y-m-d').'.log';
        $timestamp = date('Y-m-d H:i:s');
        $formattedMessage = self::interpolate($message, $context);
        $logLine = "[$timestamp] [$level] $formattedMessage\n";

        file_put_contents($logFile, $logLine, FILE_APPEND);
    }

    /**
     * 替换消息中的占位符
     *
     * @param string $message 包含占位符的消息
     * @param array $context 占位符对应的值
     * @return string 替换后的消息
     */
    protected static function interpolate($message, array $context = []) {
        // 构建替换数组
        $replace = [];
        foreach ($context as $key => $val) {
            // 如果值是对象，转换为字符串
            if (is_object($val)) {
                $val = get_class($val);
            } elseif (is_array($val) || is_resource($val)) {
                $val = gettype($val);
            }

            $replace['{'.$key.'}'] = $val;
        }

        // 替换占位符
        return strtr($message, $replace);
    }
}

// 简单日志
// Log::info('用户登录成功');

//  带上下文的日志
// Log::error('数据库连接失败', ['error' => $e->getMessage(), 'host' => 'localhost']);